#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "INetAddr.hpp"
#include <functional>
#include "ThreadPool.hpp"

using task_t = std::function<void()>;
class MessageRoute
{
private:
    std::vector<INetAddr>::iterator IsExist(const INetAddr& addr)
    {
        auto it = find(_online.begin(), _online.end(), addr);
        return it;
    }
public:
    MessageRoute()
    {}
    void AddUser(const INetAddr& addr)
    {
        if(IsExist(addr) != _online.end())
            return;
        _online.emplace_back(addr);
    }
    void DelUser(const INetAddr& addr)
    {
        auto it = IsExist(addr);
        if(it == _online.end())
            return;
        _online.erase(it);
        
    }
    void RouteHelper(int fd, const std::string message)
    {
        for (auto& in : _online)
        {
            struct sockaddr_in address = in.Addr();
            ::sendto(fd, message.c_str(), message.size(), 0, (const sockaddr*)&address, sizeof address);
        }
    }
    void Route(int fd, const std::string message, const INetAddr addr)
    {
        //1. 无论在不在，先添加用户
        AddUser(addr);

        //2. 根据message内容，删除用户
        if(message == "Q" || message == "QUIT")
            DelUser(addr);
        
        task_t t = std::bind(&MessageRoute::RouteHelper, this, fd, message);
        ThreadPool<task_t>::GetInstance()->Enqueue(t);
    }
    ~MessageRoute()
    {}
private:
    std::vector<INetAddr> _online;
};